home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 22 / PCPP #22.iso / Quake2 / q2source_12_11 / utils3 / qdata / qdata.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-12-03  |  10.1 KB  |  530 lines

  1. #include "qdata.h"
  2.  
  3. qboolean    g_compress_pak;
  4. qboolean    g_release;            // don't grab, copy output data to new tree
  5. qboolean    g_pak;                // if true, copy to pak instead of release
  6. char        g_releasedir[1024];    // c:\quake2\baseq2, etc
  7. qboolean    g_archive;            // don't grab, copy source data to new tree
  8. qboolean    do3ds;
  9. char        g_only[256];        // if set, only grab this cd
  10. qboolean    g_skipmodel;        // set true when a cd is not g_only
  11.  
  12. char        *ext_3ds = "3ds";
  13. char        *ext_tri= "tri";
  14. char        *trifileext;
  15.  
  16. /*
  17. =======================================================
  18.  
  19.   PAK FILES
  20.  
  21. =======================================================
  22. */
  23.  
  24. unsigned Com_BlockChecksum (void *buffer, int length);
  25.  
  26. typedef struct
  27. {
  28.     char    name[56];
  29.     int        filepos, filelen;
  30. } packfile_t;
  31.  
  32. typedef struct
  33. {
  34.     char    id[4];
  35.     int        dirofs;
  36.     int        dirlen;
  37. } packheader_t;
  38.  
  39. packfile_t        pfiles[16384];
  40. FILE            *pakfile;
  41. packfile_t        *pf;
  42. packheader_t    pakheader;
  43.  
  44.  
  45.  
  46. /*
  47. ==============
  48. BeginPak
  49. ==============
  50. */
  51. void BeginPak (char *outname)
  52. {
  53.     if (!g_pak)
  54.         return;
  55.  
  56.     pakfile = SafeOpenWrite (outname);
  57.  
  58.     // leave space for header
  59.     SafeWrite (pakfile, &pakheader, sizeof(pakheader));
  60.     
  61.     pf = pfiles;
  62. }
  63.  
  64.  
  65. /*
  66. ==============
  67. ReleaseFile
  68.  
  69. Filename should be gamedir reletive.
  70. Either copies the file to the release dir, or adds it to
  71. the pak file.
  72. ==============
  73. */
  74. void ReleaseFile (char *filename)
  75. {
  76.     int        len;
  77.     byte    *buf;
  78.     char    source[1024];
  79.     char    dest[1024];
  80.  
  81.     if (!g_release)
  82.         return;
  83.  
  84.     sprintf (source, "%s%s", gamedir, filename);
  85.  
  86.     if (!g_pak)
  87.     {    // copy it
  88.         sprintf (dest, "%s/%s", g_releasedir, filename);
  89.         printf ("copying to %s\n", dest);
  90.         QCopyFile (source, dest);
  91.         return;
  92.     }
  93.  
  94.     // pak it
  95.     printf ("paking %s\n", filename);
  96.     if (strlen(filename) >= sizeof(pf->name))
  97.         Error ("Filename too long for pak: %s", filename);
  98.  
  99.     len = LoadFile (source, (void **)&buf);
  100.  
  101.     if (g_compress_pak && len < 4096*1024 )
  102.     {
  103.         cblock_t    in, out;
  104.         cblock_t Huffman (cblock_t in);
  105.  
  106.         in.count = len;
  107.         in.data = buf;
  108.  
  109.         out = Huffman (in);
  110.  
  111.         if (out.count < in.count)
  112.         {
  113.             printf ("   compressed from %i to %i\n", in.count, out.count);
  114.             free (in.data);
  115.             buf = out.data;
  116.             len = out.count;
  117.         }
  118.         else
  119.             free (out.data);
  120.     }
  121.  
  122.     strcpy (pf->name, filename);
  123.     pf->filepos = LittleLong(ftell(pakfile));
  124.     pf->filelen = LittleLong(len);
  125.     pf++;
  126.  
  127.     SafeWrite (pakfile, buf, len);
  128.  
  129.     free (buf);
  130. }
  131.  
  132.  
  133. /*
  134. ==============
  135. FinishPak
  136. ==============
  137. */
  138. void FinishPak (void)
  139. {
  140.     int        dirlen;
  141.     int        d;
  142.     int        i;
  143.     unsigned    checksum;
  144.  
  145.     if (!g_pak)
  146.         return;
  147.  
  148.     pakheader.id[0] = 'P';
  149.     pakheader.id[1] = 'A';
  150.     pakheader.id[2] = 'C';
  151.     pakheader.id[3] = 'K';
  152.     dirlen = (byte *)pf - (byte *)pfiles;
  153.     pakheader.dirofs = LittleLong(ftell(pakfile));
  154.     pakheader.dirlen = LittleLong(dirlen);
  155.     
  156.     checksum = Com_BlockChecksum ( (void *)pfiles, dirlen );
  157.  
  158.     SafeWrite (pakfile, pfiles, dirlen);
  159.  
  160.     i = ftell (pakfile);
  161.      
  162.     fseek (pakfile, 0, SEEK_SET);
  163.     SafeWrite (pakfile, &pakheader, sizeof(pakheader));
  164.     fclose (pakfile);    
  165.     
  166.     d = pf - pfiles;
  167.     printf ("%i files packed in %i bytes\n",d, i);
  168.     printf ("checksum: 0x%x\n", checksum);
  169. }
  170.  
  171.  
  172. /*
  173. ===============
  174. Cmd_File
  175.  
  176. This is only used to cause a file to be copied during a release
  177. build (default.cfg, maps, etc)
  178. ===============
  179. */
  180. void Cmd_File (void)
  181. {
  182.     GetToken (false);
  183.     ReleaseFile (token);
  184. }
  185.  
  186. /*
  187. ===============
  188. PackDirectory_r
  189.  
  190. ===============
  191. */
  192. #ifdef _WIN32
  193. #include "io.h"
  194. void PackDirectory_r (char *dir)
  195. {
  196.     struct _finddata_t fileinfo;
  197.     int        handle;
  198.     char    dirstring[1024];
  199.     char    filename[1024];
  200.  
  201.     sprintf (dirstring, "%s%s/*.*", gamedir, dir);
  202.  
  203.     handle = _findfirst (dirstring, &fileinfo);
  204.     if (handle == -1)
  205.         return;
  206.  
  207.     do
  208.     {
  209.         sprintf (filename, "%s/%s", dir, fileinfo.name);
  210.         if (fileinfo.attrib & _A_SUBDIR)
  211.         {    // directory
  212.             if (fileinfo.name[0] != '.')    // don't pak . and ..
  213.                 PackDirectory_r (filename);
  214.             continue;
  215.         }
  216.         // copy or pack the file
  217.         ReleaseFile (filename);        
  218.     } while (_findnext( handle, &fileinfo ) != -1);
  219.  
  220.     _findclose (handle);
  221. }
  222. #else
  223.  
  224. #include <sys/types.h>
  225. #ifdef NeXT
  226. #include <sys/dir.h>
  227. #else
  228. #include <sys/dirent.h>
  229. #endif
  230.  
  231. void PackDirectory_r (char *dir)
  232. {
  233. #ifdef NeXT
  234.     struct direct **namelist, *ent;
  235. #else
  236.     struct dirent **namelist, *ent;
  237. #endif
  238.     int        count;
  239.     struct stat st;
  240.     int            i;
  241.     int            len;
  242.     char        fullname[1024];
  243.     char        dirstring[1024];
  244.     char        *name;
  245.     
  246.     sprintf (dirstring, "%s%s", gamedir, dir);
  247.     count = scandir(dirstring, &namelist, NULL, NULL);
  248.     
  249.     for (i=0 ; i<count ; i++)
  250.     {
  251.         ent = namelist[i];    
  252.         name = ent->d_name;
  253.  
  254.         if (name[0] == '.')
  255.             continue;
  256.     
  257.         sprintf (fullname, "%s/%s", dir, name);
  258.         sprintf (dirstring, "%s%s/%s", gamedir, dir, name);
  259.         
  260.         if (stat (dirstring, &st) == -1)
  261.             Error ("fstating %s", pf->name);
  262.         if (st.st_mode & S_IFDIR)
  263.         {    // directory
  264.             PackDirectory_r (fullname);
  265.             continue;
  266.         }
  267.  
  268.         // copy or pack the file
  269.         ReleaseFile (fullname);        
  270.     }
  271. }
  272. #endif
  273.  
  274.  
  275. /*
  276. ===============
  277. Cmd_Dir
  278.  
  279. This is only used to cause a directory to be copied during a
  280. release build (sounds, etc)
  281. ===============
  282. */
  283. void Cmd_Dir (void)
  284. {
  285.     GetToken (false);
  286.     PackDirectory_r (token);    
  287. }
  288.  
  289. //========================================================================
  290.  
  291. #define    MAX_RTEX    16384
  292. int        numrtex;
  293. char    rtex[MAX_RTEX][64];
  294.  
  295. void ReleaseTexture (char *name)
  296. {
  297.     int        i;
  298.     char    path[1024];
  299.  
  300.     for (i=0 ; i<numrtex ; i++)
  301.         if (!Q_strcasecmp(name, rtex[i]))
  302.             return;
  303.  
  304.     if (numrtex == MAX_RTEX)
  305.         Error ("numrtex == MAX_RTEX");
  306.  
  307.     strcpy (rtex[i], name);
  308.     numrtex++;
  309.  
  310.     sprintf (path, "textures/%s.wal", name);
  311.     ReleaseFile (path);
  312. }
  313.  
  314. /*
  315. ===============
  316. Cmd_Maps
  317.  
  318. Only relevent for release and pak files.
  319. Releases the .bsp files for the maps, and scans all of the files to
  320. build a list of all textures used, which are then released.
  321. ===============
  322. */
  323. void Cmd_Maps (void)
  324. {
  325.     char    map[1024];
  326.     int        i;
  327.  
  328.     while (TokenAvailable ())
  329.     {
  330.         GetToken (false);
  331.         sprintf (map, "maps/%s.bsp", token);
  332.         ReleaseFile (map);
  333.  
  334.         if (!g_release)
  335.             continue;
  336.  
  337.         // get all the texture references
  338.         sprintf (map, "%smaps/%s.bsp", gamedir, token);
  339.         LoadBSPFileTexinfo (map);
  340.         for (i=0 ; i<numtexinfo ; i++)
  341.             ReleaseTexture (texinfo[i].texture);
  342.     }
  343. }
  344.  
  345.  
  346. //==============================================================
  347.  
  348. /*
  349. ===============
  350. ParseScript
  351. ===============
  352. */
  353. void ParseScript (void)
  354. {
  355.     while (1)
  356.     {
  357.         do
  358.         {    // look for a line starting with a $ command
  359.             GetToken (true);
  360.             if (endofscript)
  361.                 return;
  362.             if (token[0] == '$')
  363.                 break;                
  364.             while (TokenAvailable())
  365.                 GetToken (false);
  366.         } while (1);
  367.     
  368.         //
  369.         // model commands
  370.         //
  371.         if (!strcmp (token, "$modelname"))
  372.             Cmd_Modelname ();
  373.         else if (!strcmp (token, "$base"))
  374.             Cmd_Base ();
  375.         else if (!strcmp (token, "$cd"))
  376.             Cmd_Cd ();
  377.         else if (!strcmp (token, "$origin"))
  378.             Cmd_Origin ();
  379.         else if (!strcmp (token, "$scale"))
  380.             Cmd_ScaleUp ();
  381.         else if (!strcmp (token, "$frame"))
  382.             Cmd_Frame ();
  383.         else if (!strcmp (token, "$skin"))
  384.             Cmd_Skin ();
  385.         else if (!strcmp (token, "$skinsize"))
  386.             Cmd_Skinsize ();
  387.         //
  388.         // sprite commands
  389.         //
  390.         else if (!strcmp (token, "$spritename"))
  391.             Cmd_SpriteName ();
  392.         else if (!strcmp (token, "$load"))
  393.             Cmd_Load ();
  394.         else if (!strcmp (token, "$spriteframe"))
  395.             Cmd_SpriteFrame ();
  396.         //
  397.         // image commands
  398.         //
  399.         else if (!strcmp (token, "$grab"))
  400.             Cmd_Grab ();
  401.         else if (!strcmp (token, "$raw"))
  402.             Cmd_Raw ();
  403.         else if (!strcmp (token, "$colormap"))
  404.             Cmd_Colormap ();
  405.         else if (!strcmp (token, "$mippal"))
  406.             Cmd_Mippal ();
  407.         else if (!strcmp (token, "$mipdir"))
  408.             Cmd_Mipdir ();
  409.         else if (!strcmp (token, "$mip"))
  410.             Cmd_Mip ();
  411.         else if (!strcmp (token, "$environment"))
  412.             Cmd_Environment ();
  413.         //
  414.         // video
  415.         //
  416.         else if (!strcmp (token, "$video"))
  417.             Cmd_Video ();
  418.         //
  419.         // misc
  420.         //
  421.         else if (!strcmp (token, "$file"))
  422.             Cmd_File ();
  423.         else if (!strcmp (token, "$dir"))
  424.             Cmd_Dir ();
  425.         else if (!strcmp (token, "$maps"))
  426.             Cmd_Maps ();
  427.         else if (!strcmp (token, "$alphalight"))
  428.             Cmd_Alphalight ();
  429.         else if (!strcmp (token, "$inverse16table" ))
  430.             Cmd_Inverse16Table();
  431.         else
  432.             Error ("bad command %s\n", token);
  433.     }
  434. }
  435.  
  436. //=======================================================
  437.  
  438. /*
  439. ==============
  440. main
  441. ==============
  442. */
  443. int main (int argc, char **argv)
  444. {
  445.     static    int        i;        // VC4.2 compiler bug if auto...
  446.     char    path[1024];
  447.  
  448.     ExpandWildcards (&argc, &argv);
  449.  
  450.     for (i=1 ; i<argc ; i++)
  451.     {
  452.         if (!strcmp(argv[i], "-archive"))
  453.         {
  454.             // -archive f:/quake2/release/dump_11_30
  455.             archive = true;
  456.             strcpy (archivedir, argv[i+1]);
  457.             printf ("Archiving source to: %s\n", archivedir);
  458.             i++;
  459.         }
  460.         else if (!strcmp(argv[i], "-release"))
  461.         {
  462.             g_release = true;
  463.             strcpy (g_releasedir, argv[i+1]);
  464.             printf ("Copy output to: %s\n", g_releasedir);
  465.             i++;
  466.         }
  467.         else if (!strcmp(argv[i], "-compress"))
  468.         {
  469.             g_compress_pak = true;
  470.             printf ("Compressing pakfile\n");
  471.         }
  472.         else if (!strcmp(argv[i], "-pak"))
  473.         {
  474.             g_release = true;
  475.             g_pak = true;
  476.             printf ("Building pakfile: %s\n", argv[i+1]);
  477.             BeginPak (argv[i+1]);
  478.             i++;
  479.         }
  480.         else if (!strcmp(argv[i], "-only"))
  481.         {
  482.             strcpy (g_only, argv[i+1]);
  483.             printf ("Only grabbing %s\n", g_only);
  484.             i++;
  485.         }
  486.         else if (!strcmp(argv[i], "-3ds"))
  487.         {
  488.             do3ds = true;
  489.             printf ("loading .3ds files\n");
  490.         }
  491.         else if (argv[i][0] == '-')
  492.             Error ("Unknown option \"%s\"", argv[i]);
  493.         else
  494.             break;
  495.     }
  496.  
  497.     if (i >= argc)
  498.         Error ("usage: qgrab [-archive <directory>] [-release <directory>] [-only <model>] [-3ds] file.qgr");
  499.  
  500.     if (do3ds)
  501.         trifileext = ext_3ds;
  502.     else
  503.         trifileext = ext_tri;
  504.  
  505.     for ( ; i<argc ; i++)
  506.     {
  507.         printf ("--------------- %s ---------------\n", argv[i]);
  508.         // load the script
  509.         strcpy (path, argv[i]);
  510.         DefaultExtension (path, ".qdt");
  511.         SetQdirFromPath (path);
  512.         LoadScriptFile (ExpandArg(path));
  513.         
  514.         //
  515.         // parse it
  516.         //
  517.         ParseScript ();
  518.  
  519.         // write out the last model
  520.         FinishModel ();
  521.         FinishSprite ();
  522.     }
  523.  
  524.     if (g_pak)
  525.         FinishPak ();
  526.  
  527.     return 0;
  528. }
  529.  
  530.